import io

from django.http import HttpResponse
from django.shortcuts import render

from django.db.models import Q
from openpyxl.workbook import Workbook

from patient.models import SourceModel, AppointmentModel, PatientModel, TriageModel, BookingModel
from patient.serializers import SourceSerializer, AppointmentSerializer, PatientSerializer, BookingSerializer, \
    TriageSerializer

from rest_framework.generics import ListAPIView
from rest_framework.viewsets import ModelViewSet
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.pagination import PageNumberPagination


# Create your views here.


class SourceView(ModelViewSet):
    queryset = SourceModel.objects.all()
    serializer_class = SourceSerializer
    lookup_field = "id"
    lookup_url_kwarg = "id"


class AppointmentView(ModelViewSet):
    queryset = AppointmentModel.objects.all()
    serializer_class = AppointmentSerializer
    lookup_field = "id"
    lookup_url_kwarg = "id"


class pagination(PageNumberPagination):
    page_size = 1
    max_page_size = 4
    page_query_param = "page"
    page_size_query_param = "size"


class PatientView(ModelViewSet):
    queryset = PatientModel.objects.all()
    serializer_class = PatientSerializer
    lookup_field = "id"
    lookup_url_kwarg = "id"

    pagination_class = pagination

    def get_queryset(self):
        query = Q()
        pname = self.request.query_params.get("pname")
        source = self.request.query_params.get("source")
        dday = self.request.query_params.get("dday")

        if pname:
            query &= Q(pname__contains=pname)
        if source:
            query &= Q(source=int(source))
        if dday:
            query &= Q(dday=dday)

        return self.queryset.filter(query)


# 定义下载患者数据的函数
def download_patient_data(request):
    # 创建一个新的 Excel 工作簿
    wb = Workbook()
    # 获取工作簿的活动工作表
    ws = wb.active
    # 设置表头
    headers = ['序号', '患者姓名', '性别', '预约日期', '电话', '患者来源', '服务内容', '预约状态', '凭证核销']
    ws.append(headers)
    # 从数据库中获取患者数据并添加到 Excel 表格中
    patients = PatientModel.objects.all()
    # 遍历患者数据，从1开始计数
    for index, patient in enumerate(patients, start=1):
        # 处理外键关联数据，如果没有关联则显示 '无'
        source_name = patient.source.sname if patient.source else '无'  # 处理外键关联数据，如果没有关联则显示 '无'
        appointment_name = patient.appointment.aname if patient.appointment else '无'  # 处理外键关联数据，如果没有关联则显示 '无'
        # 构建一行数据
        row = [
            index,
            patient.pname,
            patient.sex,
            patient.dday,
            patient.phone,
            source_name,
            patient.content,
            appointment_name,
            patient.writeoff
        ]
        # 将一行数据添加到工作表中
        ws.append(row)

    # 将工作簿保存到内存中的二进制流
    buffer = io.BytesIO()
    wb.save(buffer)
    # 将文件指针移动到流的开头
    buffer.seek(0)

    # 创建 HttpResponse 对象，设置响应头
    response = HttpResponse(buffer, content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
    # 设置响应头，指定文件名
    response['Content-Disposition'] = 'attachment; filename="patient_data.xlsx"'
    # 返回响应对象
    return response


class TriageView(ModelViewSet):
    queryset = TriageModel.objects.all()
    serializer_class = TriageSerializer
    lookup_field = "id"
    lookup_url_kwarg = "id"


class BookingView(ModelViewSet):
    queryset = BookingModel.objects.all()
    serializer_class = BookingSerializer
    lookup_field = "id"
    lookup_url_kwarg = "id"

    pagination_class = pagination

    def get_queryset(self):
        query = Q()
        bname = self.request.query_params.get("bname")
        source = self.request.query_params.get("source")
        dday = self.request.query_params.get("dday")

        if bname:
            query &= Q(bname__contains=bname)
        if source:
            query &= Q(source=int(source))
        if dday:
            query &= Q(dday=dday)

        return self.queryset.filter(query)


# 定义下载预约患者数据的函数
def download_appointment_data(request):
    # 创建一个新的 Excel 工作簿
    wb = Workbook()
    # 获取工作簿的活动工作表
    ws = wb.active
    # 设置表头
    headers = ['序号', '患者姓名', '性别', '年龄', '档案号', '预约日期', '预约医生', '分诊状态', '服务状态', '病情描述']
    ws.append(headers)
    # 从数据库中获取患者数据并添加到 Excel 表格中
    patients = BookingModel.objects.all()
    # 遍历患者数据，从1开始计数
    for index, patient in enumerate(patients, start=1):
        # 处理外键关联数据，如果没有关联则显示 '无'
        source_name = patient.source.sname if patient.source else '无'  # 处理外键关联数据，如果没有关联则显示 '无'
        appointment_name = patient.appointment.aname if patient.appointment else '无'  # 处理外键关联数据，如果没有关联则显示 '无'
        Triage_name = patient.Triage.tname if patient.Triage else '无'  # 处理外键关联数据，如果没有关联则显示 '无'
        # 构建一行数据
        row = [
            index,
            patient.bname,
            patient.sex,
            patient.age,
            patient.dangan,
            patient.dday,

            source_name,
            Triage_name,
            appointment_name,

            patient.writeoff
        ]
        # 将一行数据添加到工作表中
        ws.append(row)

    # 将工作簿保存到内存中的二进制流
    buffer = io.BytesIO()
    wb.save(buffer)
    # 将文件指针移动到流的开头
    buffer.seek(0)

    # 创建 HttpResponse 对象，设置响应头
    response = HttpResponse(buffer, content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
    # 设置响应头，指定文件名
    response['Content-Disposition'] = 'attachment; filename="booking_data.xlsx"'
    # 返回响应对象
    return response
